package com.cashmama.market.api.application.controller.risk;

import com.alibaba.fastjson.JSONObject;
import com.cashmama.market.api.application.annos.VisitorAccessible;
import com.cashmama.market.api.application.controller.risk.request.AdvanceLivenessDetectionRequest;
import com.cashmama.market.api.application.controller.risk.request.AntiHackVO;
import com.cashmama.market.api.application.controller.risk.response.AdvanceLivenessDetectionLicenseVO;
import com.cashmama.market.api.application.controller.risk.response.AdvanceLivenessDetectionVO;
import com.cashmama.market.api.application.controller.risk.response.AntiHackResponse;
import com.cashmama.market.api.domain.integration.AdvanceAiIntegrationService;
import com.cashmama.market.api.domain.vo.RequestLocalInfo;
import com.cashmama.market.api.domain.vo.aadhaar.AdvanceLivenessDetection;
import com.cashmama.market.api.domain.vo.aadhaar.AdvanceLivenessDetectionLicence;
import com.cashmama.market.api.infras.config.ApolloConfigUtil;
import com.cashmama.market.api.infras.exception.ApplicationException;
import com.cashmama.market.api.infras.handler.ApiResponse;
import com.cashmama.market.api.infras.utils.OSSFixUtils;
import com.fqgj.common.api.Response;
import com.fqgj.common.api.annotations.ParamsValidate;
import com.fqgj.xjd.user.client.UserService;
import com.fqgj.xjd.user.client.response.UserLiveRes;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * 反欺诈
 *
 * @author moss
 * 2019-05-30
 */
@Controller
@RequestMapping("/face")
public class AntiHackController {
    private static final Logger logger = LoggerFactory.getLogger(AntiHackController.class);
    @Autowired
    AdvanceAiIntegrationService advanceAiIntegrationService;
    @Autowired
    ApolloConfigUtil apolloConfigUtil;

    @Autowired
    private UserService userService;

    @RequestMapping("/liveness_anti_hack")
    @ResponseBody
    @VisitorAccessible
    public ApiResponse<AntiHackResponse> antiHack(@RequestBody AntiHackVO antiHackVO) {


        byte[] bytes = new byte[0];
        try {
            bytes = IOUtils.toByteArray(new URL(OSSFixUtils.fixOssUrl(antiHackVO.getLivenessAntiHack())));
        } catch (IOException e) {
            logger.error("URL 转换失败 e:" + e);
        }
        if (bytes.length == 0) {
            logger.info("图片解析错误，url:{}", antiHackVO.getLivenessAntiHack());
            throw new ApplicationException("Face recognition failed");
        }
        logger.info("antiHack日志1,url:{},length:{}", antiHackVO.getLivenessAntiHack(), bytes.length);
        String userCode = RequestLocalInfo.getCurrentUser() != null ? RequestLocalInfo.getCurrentUser().getUserCode() : "";
        AntiHackResponse antiHackResponse = new AntiHackResponse();
        if (!apolloConfigUtil.faceHackOpen()) {//关闭调用开关
            antiHackResponse.setPass(true);
            return new ApiResponse(antiHackResponse);
        }
        Response<Double> response = advanceAiIntegrationService.antiHack(bytes);

        logger.info("antiHack日志2,response:{}", JSONObject.toJSONString(response));

        if (!response.isSuccess()) {
            throw new ApplicationException(response.getMsg());
        }

        boolean pass = false;
        if (response.getData() <= apolloConfigUtil.getHackScoreThreshold()) {
            pass = true;
        }
        antiHackResponse.setPass(pass);
        logger.info("反欺诈结果,pass:{},userCode:{}", pass, userCode);
        if (!pass) {
            throw new ApplicationException("Face recognition failed");
        }
        return new ApiResponse(antiHackResponse);
    }

    /**
     * advance活体检测获取licence
     *
     * @return
     */
    @RequestMapping("/advance/liveness/license")
    @ResponseBody
    public ApiResponse<AdvanceLivenessDetectionLicenseVO> getDetectionLicense() {

        if (!apolloConfigUtil.getAdvanceFaceDetectionOpen()) {
            AdvanceLivenessDetectionLicenseVO advanceLivenessDetectionVO = new AdvanceLivenessDetectionLicenseVO();
            advanceLivenessDetectionVO.setUseAdvanceDetection(false);
            return new ApiResponse(advanceLivenessDetectionVO);
        }
        String packageName = RequestLocalInfo.getRequestBasicInfo().getPackageName();
        String userCode = RequestLocalInfo.getCurrentUser().getUserCode();
        AdvanceLivenessDetectionLicence advanceLivenessDetection = advanceAiIntegrationService.advanceLivenessDetectionLicense(userCode, packageName);
        return new ApiResponse(new AdvanceLivenessDetectionLicenseVO(advanceLivenessDetection, apolloConfigUtil.getAdvanceFaceDetectionOpen()));
    }

    /**
     * advance活体检测
     *
     * @return
     */
    @ParamsValidate
    @RequestMapping("/advance/liveness/detection")
    @ResponseBody
    public ApiResponse<AdvanceLivenessDetectionVO> detection(@RequestBody AdvanceLivenessDetectionRequest request) {

        if (!apolloConfigUtil.getAdvanceFaceDetectionOpen()) {
            AdvanceLivenessDetectionLicenseVO advanceLivenessDetectionVO = new AdvanceLivenessDetectionLicenseVO();
            advanceLivenessDetectionVO.setUseAdvanceDetection(true);
            return new ApiResponse(advanceLivenessDetectionVO);
        }
        String userCode = RequestLocalInfo.getCurrentUser().getUserCode();
        AdvanceLivenessDetection advanceLivenessDetection = advanceAiIntegrationService.advanceLivenessDetection(userCode, request.getLivenessId());

        userService.addUserLiveRes(new UserLiveRes().setUserCode(userCode).setScore(advanceLivenessDetection.getLivenessScore() + ""));

        AdvanceLivenessDetectionVO advanceLivenessDetectionVO = new AdvanceLivenessDetectionVO();
        if (advanceLivenessDetection.getLivenessScore() < 50) {
            advanceLivenessDetectionVO.setPass(false);
            return new ApiResponse(advanceLivenessDetectionVO);
        }
        advanceLivenessDetectionVO.setPass(true);
        advanceLivenessDetectionVO.setImageUrl(advanceLivenessDetection.getDetectionResult());

        return new ApiResponse(advanceLivenessDetectionVO);
    }

    private byte[] toByteArray(String path) throws Exception {
        byte[] data = null;
        ByteArrayOutputStream output = null;
        InputStream input = null;
        try {
            URL url = new URL(path);
            HttpURLConnection httpUrl = (HttpURLConnection) url.openConnection();
            httpUrl.connect();
            httpUrl.getInputStream();
            input = httpUrl.getInputStream();
            output = new ByteArrayOutputStream();
            byte[] buf = new byte[1024];
            int numBytesRead = 0;
            while ((numBytesRead = input.read(buf)) != -1) {
                output.write(buf, 0, numBytesRead);
            }
            data = output.toByteArray();
        } catch (Exception e) {
            logger.error(" to byte array exception", e);
            throw e;
        } finally {
            if (output != null) {
                output.close();
            }
            if (input != null) {
                input.close();
            }
        }
        return data;
    }
}
